import { Vector3 } from "../3rdParty/three.js/build/three.module.js";
import AmmoHelper, { toAmmoType } from "./AmmoHelper.js";

/**
 * 物理世界
 */
const rigidBodys = [];  // 刚体列表
const constraints = []; // 约束列表

class Physics {
  lastTime = -1;

  constructor() {

  }

  async init() {

    await AmmoHelper.initAmmo();
    this.world = AmmoHelper.initPhysics();

  }

  add( obj ) {

    if( !obj.physicsBody ) {

      // 创建物理模型
      if( !obj.collider ) {
        obj.collider = obj.visual;
      }

      if( !obj.physicsShape ) {

        AmmoHelper.createPhysicsShape( obj );

      }

      // 生成刚体模型
      AmmoHelper.updateRigidBody( obj );

    }

    if( obj.physicsBody instanceof Array ) {
      
      for( var i = 0, il = obj.physicsBody.length; i < il; i++ ) {
        this.world.addRigidBody( obj.physicsBody[i] );
      }
      rigidBodys.push( ...obj.physicsBody );

    }
    else {
      this.world.addRigidBody( obj.physicsBody );
      
      // 重力参数
      if( obj.disableGravity ) {
        AmmoHelper.disableGravity( obj.physicsBody );
      }

      rigidBodys.push( obj.physicsBody );
    }

    if( obj.constraints.length > 0 ) {
      for( var i = 0, il = obj.constraints.length; i < il; i++ ) {
        
        const config = obj.constraints[i];
        
        config["rbA"] = obj.physicsBody[ config.indexA ];
        config["rbB"] = obj.physicsBody[ config.indexB ];

        if( config.handle ) {
          config.handle = undefined;
        }

        const constraint = AmmoHelper.createConstraint( config );

        if( constraint ){
          this.world.addConstraint( constraint, true );
          config.handle = constraint;
          constraints.push( constraint );
          // constraint.enableAngularMotor( true, 1.5, 10 );
          // console.log( constraint)
        }

      }
    }

  }

  // 清空物理世界
  clear() {

    for( var i=0, il=rigidBodys.length; i < il; i++ ) {
      this.world.removeRigidBody( rigidBodys[i] );
    }

    rigidBodys.length = 0;

    for( var i=0, il=constraints.length; i < il; i++ ) {
      this.world.removeConstraint( constraints[i] );
    }

    constraints.length = 0;
    
  }

  update() {
    const time = performance.now();

		if ( this.lastTime > 0 ) {

			const delta = ( time - this.lastTime ) / 1000;

			// console.time( 'world.step' );
			this.world.stepSimulation( delta, 10 );
			// console.timeEnd( 'world.step' );

		}

		this.lastTime = time;
  }

}

export default Physics;